﻿#include "db_api_.h"

int add_like(char* path, int likeID)
{
	int res = 0;
	unsigned int br;
	LIKERECORD rec = {0};
	char fname[MAXPATH];
	split_path(path, 0, fname, 0, 0);

	if(hDB->like_count[likeID] >= MAXLIKERECORD)
	{
		return -1;
	}

	strcpy(rec.path, path);
	name_to_utf8((const unsigned char*)fname, (unsigned char*)rec.fname, MAXUTF8NAME);

	res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * (MAXLIKERECORD * (long long)likeID + hDB->like_count[likeID]));
	res += f_write(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
	hDB->like_count[likeID] ++;

	return res;
}

int remove_like(char* path, int likeID)
{
	unsigned int i, j;
	int res = 0;
	unsigned int br;
	LIKERECORD rec;

	res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * MAXLIKERECORD * (long long)likeID);
	for (i = 0, j = 0; i < hDB->like_count[likeID]; i++)
	{
		DB_SLP
		res += f_read(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
		if (res || sizeof(LIKERECORD) != br)	break;
		if (dircmp(path, rec.path) != 0)
		{
			if (i != j)
			{
				long long tmp_offset = f_tell(&hDB->fdb);
				res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * (MAXLIKERECORD * (long long)likeID + j));
				res += f_write(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
				res += f_lseek(&hDB->fdb, tmp_offset);
			}
			j++;
		}
	}
	hDB->like_count[likeID] = j;
	return res;
}

int scanlike(int likeID)
{
	unsigned int i,j;
	int res = 0;
	unsigned int br;
	LIKERECORD rec;

	res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * MAXLIKERECORD * (long long)likeID);
	for(i=0,j=0; i<hDB->like_count[likeID]; i++)
	{
		int percent = i * (100/ MAXLIKETYPE) / hDB->like_count[likeID];
		percent += likeID * (100 / MAXLIKETYPE);
		if (percent > 100)	percent = 100;
		hDB->cb(-555, percent);
		DB_SLP

		res += f_read(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
		if(is_archive(rec.path))
		{
			if(i != j)
			{
				long long tmp_offset = f_tell(&hDB->fdb);
				res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * (MAXLIKERECORD * (long long)likeID + j));
				res += f_write(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
				res += f_lseek(&hDB->fdb, tmp_offset);
			}
			j++;
		}
	}
	hDB->like_count[likeID] = j;
	return res;
}

int like_build(void)
{
	int likeID;
	int res = 0;

	assert(hDB->mount == 1);

	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;

	for(likeID = 0; likeID < MAXLIKETYPE; likeID++)
	{
		res += scanlike(likeID);
	}

	hDB->dirty &= ~MODULE_LIKE;
	res += f_close(&hDB->fdb);
	hDB->cb(-666, 100);

	return 0;
}

int get_like_records(int likeID, unsigned int offset, LIKERECORD* records, unsigned int cnt)
{
	unsigned int ret = 0;
	unsigned int i;
	int res = 0;
	unsigned int br;

	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;
	
	res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * (MAXLIKERECORD * (long long)likeID + offset));

	for(i=offset; ret<cnt && i<hDB->like_count[likeID]; i++)
	{
		res += f_read(&hDB->fdb, &records[ret++], sizeof(LIKERECORD), &br);
	}

	res += f_close(&hDB->fdb);

	return res ? -1 : ret;
}

int get_like_name(int likeID, unsigned int offset, RECUTF8NAME* fname, unsigned int cnt)
{
	unsigned int ret = 0;
	unsigned int i;
	int res = 0;
	unsigned int br;
	LIKERECORD rec;

	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;
	
	res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * (MAXLIKERECORD * (long long)likeID + offset));

	for(i=offset; ret<cnt && i<hDB->like_count[likeID]; i++)
	{
		res += f_read(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
		memcpy(fname[ret++], rec.fname, MAXUTF8NAME);
	}

	res += f_close(&hDB->fdb);

	return res ? -1 : ret;
}

int is_like(char* path, int* like)
{
	unsigned int likeID, i;
	int res = 0;
	unsigned int br;
	LIKERECORD rec;

	*like = 0;

	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;

	for (likeID = 0; likeID < MAXLIKETYPE; likeID++)
	{
		res += f_lseek(&hDB->fdb, sizeof(LIKERECORD) * MAXLIKERECORD * (long long)likeID);
		for(i=0; i<hDB->like_count[likeID]; i++)
		{
			res += f_read(&hDB->fdb, &rec, sizeof(LIKERECORD), &br);
			if(dircmp(path, rec.path) == 0)
			{
				(*like) |= 1<<likeID;
				break;
			}
		}
	}

	res += f_close(&hDB->fdb);

	return res;
}

int set_like(char* path, int like)
{
	int res = 0;

	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;

	if(like > 0)
	{
		res += add_like(path, like-1);
	}
	else
	{
		res += remove_like(path, -like-1);
	}

	res += f_close(&hDB->fdb);

	return res;
}

int delete_like(char* path)
{
	unsigned int likeID;
	int res = 0;
	res += f_open(&hDB->fdb, (const char*)(F_DBLIKE), (unsigned char)(FA_READ | FA_WRITE));
	if (res) return -1;

	for (likeID = 0; likeID < MAXLIKETYPE; likeID++)
	{
		remove_like(path, likeID);
	}

	res += f_close(&hDB->fdb);
	return res;
}
